﻿using Fibot.Module.WangDianTong;
using Newtonsoft.Json;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace Fibot.Module.WangDianTong;

/// <summary>
/// 请求类
/// </summary>
class WdtClient
{
    private readonly WdtOptions options = new WdtOptions();

    /// <summary>
    /// 构造器
    /// </summary>
    public WdtClient()
    {
    }

    /// <summary>
    /// 构造器
    /// </summary>
    /// <param name="_options"></param>
    public WdtClient(WdtOptions _options)
    {
        this.options = _options;
    }

    /// <summary>
    /// 发起请求
    /// </summary>
    /// <param name="serviceName"></param>
    /// <param name="param"></param>
    /// <returns></returns>
    public string wdtOpenapi(string serviceName, Dictionary<string, object> param)
    {
        HttpWebRequest request = null;
        HttpWebResponse response = null;
        Stream serviceRequestBodyStream = null;
        try
        {
            request = (HttpWebRequest)WebRequest.Create(options.BaseUrl + serviceName);
            request.Credentials = CredentialCache.DefaultCredentials;
            request.KeepAlive = false;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            UTF8Encoding encoding = new UTF8Encoding();
            string postData = CreateParam(param, true);
            byte[] bodyBytes = encoding.GetBytes(postData);
            request.ContentLength = bodyBytes.Length;
            using (serviceRequestBodyStream = request.GetRequestStream())
            {
                serviceRequestBodyStream.Write(bodyBytes, 0, bodyBytes.Length);
                serviceRequestBodyStream.Close();
                using (response = (HttpWebResponse)request.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        string result = reader.ReadToEnd();
                        reader.Close();
                        return result;
                    }
                }
            }
        }
        catch (Exception)
        {
            //LogManager.WriteError(ex, "Post");
            throw;
        }
        finally
        {
            if (response != null)
            {
                response.Close();
            }
            if (request != null)
            {
                request.Abort();
            }
        }
    }

    /// <summary>
    /// 参数排序 并加密
    /// </summary>
    /// <param name="isLower"></param>
    /// <returns></returns>
    private string CreateParam(Dictionary<string, object> param, bool isLower = false)
    {
        //排序
        param = param.OrderBy(r => r.Key).ToDictionary(r => r.Key, r => r.Value);

        StringBuilder sb = new StringBuilder();
        int i = 0;
        foreach (var item in param)
        {
            if (item.Key == "sign")
                continue;
            if (i > 0)
            {
                sb.Append(";");
            }
            i++;
            sb.Append(item.Key.Length.ToString("00"));
            sb.Append("-");
            sb.Append(item.Key);
            sb.Append(":");
            sb.Append((item.Value ?? "").ToString()?.Length.ToString("0000"));
            sb.Append("-");
            sb.Append(item.Value);
        }
        if (param.ContainsKey("sign"))
        {
            param["sign"] = isLower ? MD5Encrypt(sb + options.Appsecret).ToLower() : MD5Encrypt(sb + options.Appsecret);
        }
        else
        {
            param.Add("sign", isLower ? MD5Encrypt(sb + options.Appsecret).ToLower() : MD5Encrypt(sb + options.Appsecret));
        }
        sb = new StringBuilder();
        i = 0;
        foreach (var item in param)
        {
            if (i == 0)
                sb.Append(string.Format("{0}={1}", item.Key, HttpUtility.UrlEncode(item.Value.ToString(), Encoding.UTF8)));
            else
                sb.Append(string.Format("&{0}={1}", item.Key, HttpUtility.UrlEncode(item.Value.ToString(), Encoding.UTF8)));
            i++;
        }

        return sb.ToString();
    }

    /// <summary>
    /// MD5加密
    /// </summary>
    /// <param name="strText"></param>
    /// <returns></returns>
    private string MD5Encrypt(string strText)
    {
        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] result = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(strText));
        string strMd5 = BitConverter.ToString(result);
        strMd5 = strMd5.Replace("-", "");
        return strMd5;// System.Text.Encoding.Default.GetString(result);
    }

}
public static class Utils
{
    public static string ToJsonString(this object obj)
    {
        if (obj == null)
            return null;
        return JsonConvert.SerializeObject(obj);
    }

    public static object ToJsonString(this string json)
    {
        return json == null ? null : JsonConvert.DeserializeObject(json);
    }
}